package cn.edu.njnu.opengmpback.Modeling.service;


import cn.edu.njnu.opengmpback.Modeling.dao.ComputeModelDao;
import cn.edu.njnu.opengmpback.Modeling.dao.ConceptModelDao;
import cn.edu.njnu.opengmpback.Modeling.dao.ConceptMaterialDao;
import cn.edu.njnu.opengmpback.Modeling.dao.ProjectDao;
import cn.edu.njnu.opengmpback.Modeling.entity.ComputeModel;
import cn.edu.njnu.opengmpback.Modeling.entity.dto.*;
import cn.edu.njnu.opengmpback.Modeling.entity.ConceptModel;
import cn.edu.njnu.opengmpback.Modeling.entity.ConceptMaterial;
import cn.edu.njnu.opengmpback.Modeling.entity.ConceptModelItems;
import cn.edu.njnu.opengmpback.Modeling.entity.Project;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.edu.njnu.opengmpback.common.utils.CommonService;
import cn.edu.njnu.opengmpback.common.utils.JsonResult;
import cn.edu.njnu.opengmpback.common.utils.ModelUtils;
import cn.edu.njnu.opengmpback.common.utils.ResultUtils;
import cn.edu.njnu.opengmpback.resource.dao.UserDataDao;
import cn.edu.njnu.opengmpback.resource.entity.ModelItem;
import cn.edu.njnu.opengmpback.resource.entity.ResourceData;
//import cn.edu.njnu.opengmpback.resource.entity.VisualDataItem;
import cn.edu.njnu.opengmpback.user.dao.UserDao;
import cn.edu.njnu.opengmpback.user.entity.UserEntity;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.MediaType;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.web.client.RestTemplate;

@Service
@Slf4j
public class  ConceptModelService {

    @Value("${dataStoreDir}")
    private String dataStoreDir;

    @Value("${conceptMaterialUploadDir}")
    private String conceptMaterialUploadDir;

    @Value("${conceptModelUploadDir}")
    private String conceptModelUploadDir;

    @Value("${pythonInterpreter}")
    private String pythonInterpreter;

    @Autowired
    CommonService commonService;

    @Autowired
    ConceptModelDao conceptModelDao;

    @Autowired
    ConceptMaterialDao conceptMaterialDao;

    @Autowired
    UserDao userDao;

    @Autowired
    ProjectDao projectDao;

    @Qualifier("webApplicationContext")
    @Autowired
    private ResourceLoader resourceLoader;

    /////////////////////////////////////////////////概念建模////////////////////////////////////////////////////////

    public JsonResult createConceptModel(CreateConceptModelDTO createConceptModelDTO, MultipartFile imgFile,String userId) {
        try {
            Optional<Project> projectDB = projectDao.findById(createConceptModelDTO.getProjectId());
            if(!projectDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }

            UserEntity user = userDao.findByUserId(userId);
            //创建的conceptModel对象
            ConceptModel conceptModel = new ConceptModel();
            conceptModel.setCreatorId(user.getUserId());
            conceptModel.setCreatorName(user.getName());
            conceptModel.setCreatorEmail(user.getEmail());

            //设置conceptModel的属性
            BeanUtils.copyProperties(createConceptModelDTO,conceptModel);
            if(conceptModel.getConceptData() == null){
                conceptModel.setConceptData("");
            }

            File folder = new File(conceptModelUploadDir);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            // 定义允许的图片类型
            List<String> allowedContentTypes = Arrays.asList(
                    MediaType.IMAGE_JPEG_VALUE,  // "image/jpeg"
                    MediaType.IMAGE_PNG_VALUE,   // "image/png"
                    MediaType.IMAGE_GIF_VALUE    // "image/gif"
            );

            //判断文件类型
            if (!allowedContentTypes.contains(imgFile.getContentType())) {
                return ResultUtils.error(-1,"封面文件类型不允许");
            }

            //图像
            if (imgFile.isEmpty()) {
                conceptModel.setModelWebAddress("");
            }else {
                //将文件保存到指定位置
                String modelFileName = imgFile.getOriginalFilename(); //eg: XXX.js
                String modelFileMainName= FileNameUtil.mainName(modelFileName); // XXX
                String modelFileExtName = FileNameUtil.extName(modelFileName); //js
                String modelFileNewName= IdUtil.objectId()+"."+modelFileExtName;
                File saveImgFile = new File(folder, modelFileNewName);//eg: E:\\TEMP\\1231231.js
                imgFile.transferTo(saveImgFile);
                conceptModel.setModelStoreName(modelFileNewName);
                conceptModel.setModelWebAddress("/store/conceptModelFile/"+modelFileNewName);
                conceptModel.setModelRelativePath("/conceptModelFile/"+modelFileNewName);
            }

            conceptModelDao.save(conceptModel);
            //项目绑定概念模型Id
            Project project = projectDB.get();
            List<String> conceptModelIdList = project.getConceptModelIdList();
            conceptModelIdList.add(conceptModel.getId());
            project.setConceptModelIdList(conceptModelIdList);
            projectDao.save(project);
            return ResultUtils.success(conceptModel);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.error(-1,"创建概念模型失败");
        }
    }

    public JsonResult OpenConceptModel(String conceptModelId) {
        try{
            Optional<ConceptModel> conceptModelDB = conceptModelDao.findById(conceptModelId);
            if (!conceptModelDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            ConceptModel conceptModel = conceptModelDB.get();
            return ResultUtils.success(conceptModel);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtils.error(-1,"打开概念模型失败");
        }

    }

    public JsonResult getConceptModel(String projectId) {
        try {
            ConceptModel conceptModel = conceptModelDao.findByProjectId(projectId);
            return ResultUtils.success(conceptModel);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.error(-1,"获取概念模型失败");
        }
    }

    public JsonResult searchConceptModelList(ConceptModelPageDTO conceptModelFindDTO) {
        try{
            Pageable pageable = commonService.getConceptModelPageable(conceptModelFindDTO);
            Page<ConceptModelItems> re = conceptModelDao.findAllByProjectIdAndNameLikeIgnoreCase(conceptModelFindDTO.getProjectId(),conceptModelFindDTO.getSearchText(),pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败！");
        }
    }

    public JsonResult searchAllConceptModelList(ConceptModelPageDTO conceptModelFindDTO) {
        try{
            Pageable pageable = commonService.getConceptModelPageable(conceptModelFindDTO);
            Page<ConceptModelItems> re = conceptModelDao.findAllByNameLikeIgnoreCase(conceptModelFindDTO.getSearchText(),pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败！");
        }
    }


    public JsonResult UpdateConceptModel(String conceptModelId,CreateConceptModelDTO createConceptModelDTO, MultipartFile imgFile) throws IOException {
        Optional<ConceptModel> conceptModelDB = conceptModelDao.findById(conceptModelId);
        if (!conceptModelDB.isPresent()){
            return ResultUtils.error(-1,"项目不存在");
        }
        ConceptModel conceptModel = conceptModelDB.get();
        if(createConceptModelDTO.getName() != null){
            conceptModel.setName(createConceptModelDTO.getName());
        }
        if(createConceptModelDTO.getDescription() != null){
            conceptModel.setDescription(createConceptModelDTO.getDescription());
        }
        if (createConceptModelDTO.getConceptData() != null){
            conceptModel.setConceptData(createConceptModelDTO.getConceptData());
        }

        // 定义允许的图片类型
        List<String> allowedContentTypes = Arrays.asList(
                MediaType.IMAGE_JPEG_VALUE,  // "image/jpeg"
                MediaType.IMAGE_PNG_VALUE,   // "image/png"
                MediaType.IMAGE_GIF_VALUE    // "image/gif"
        );

        //判断文件类型
        if (!allowedContentTypes.contains(imgFile.getContentType())) {
            return ResultUtils.error(-1,"封面文件类型不允许");
        }

        //图像
        if (imgFile.isEmpty()) {
            conceptModel.setModelWebAddress("");
        }else {
            File folder = new File(conceptModelUploadDir);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            //删除原文件
            String filePath=dataStoreDir+conceptModel.getModelRelativePath();
            File file = new File(filePath);

            if (file.exists()) {
                FileUtil.del(filePath);
                System.out.println(filePath+"文件删除成功");
            } else {
                System.out.println("文件路径不存在");
            }

            //将文件保存到指定位置
            String modelFileName = imgFile.getOriginalFilename(); //eg: XXX.js
            String modelFileExtName = FileNameUtil.extName(modelFileName); //js
            String modelFileNewName= IdUtil.objectId()+"."+modelFileExtName;
            File saveImgFile = new File(folder, modelFileNewName);//eg: E:\\TEMP\\1231231.js
            imgFile.transferTo(saveImgFile);
            conceptModel.setModelStoreName(modelFileNewName);
            conceptModel.setModelWebAddress("/store/conceptModelFile/"+modelFileNewName);
            conceptModel.setModelRelativePath("/conceptModelFile/"+modelFileNewName);

        }
        conceptModelDao.save(conceptModel);
        return ResultUtils.success("更新成功");
    }

    public JsonResult DeleteConceptModel(String conceptModelId) {
        Optional<ConceptModel> conceptModelDB = conceptModelDao.findById(conceptModelId);
        if (!conceptModelDB.isPresent()){
            return ResultUtils.error(-1,"项目不存在");
        }
        ConceptModel conceptModel = conceptModelDB.get();
        conceptModelDao.deleteById(conceptModelId);
        Project project = projectDao.findById(conceptModel.getProjectId()).get();
        project.getConceptModelIdList().remove(conceptModelId);
        projectDao.save(project);
        return ResultUtils.success("删除成功");
    }

    /////////////////////////////////////////////////概念建模素材////////////////////////////////////////////////////////
    //TODO：改回配置文件信息
    public JsonResult backgroundRemove(MultipartFile imgFile) throws IOException{
        String url = "http://112.4.132.6:8083/data";
        String inputBaseUrl = "http://112.4.132.6:8083/data/";
        String outputUrl = null;
        RestTemplate restTemplate = new RestTemplate();
        // 创建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        // 创建请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

        // 将 MultipartFile 转换为 ByteArrayResource 或 InputStreamResource
        ByteArrayResource fileResource = new ByteArrayResource(imgFile.getBytes()) {
            @Override
            public String getFilename() {
                return imgFile.getOriginalFilename(); // 返回文件名
            }
        };

        // 添加文件到请求体
        body.add("datafile", fileResource);

        // 创建请求实体
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

        // 发送POST请求
        ResponseEntity<JSONObject> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, JSONObject.class);
        if (response.getStatusCode() != HttpStatus.OK) {
            return ResultUtils.error(-1, "请求失败");
        }
        if ( (int) response.getBody().get("code") == 1) {
            // 获取响应体
            JSONObject responseBody = response.getBody();

            // 获取嵌套的 "id" 值
            String id = responseBody
                    .getJSONObject("data")    // 获取外层 "data"
                    .getString("id");         // 获取 "id"

            String inputUrl = inputBaseUrl + id;

            // 设置传递给Python脚本的参数
            Resource resource = resourceLoader.getResource("classpath:static/myScripts/remove_bg.py");
            // 获取文件的绝对路径
            File file = resource.getFile();
            String pyPath = file.getAbsolutePath();
            String[] cmd = {pythonInterpreter, pyPath, inputUrl};  // 添加所需的参数
            ProcessBuilder pb = new ProcessBuilder(cmd);
            try {

                // 启动Python脚本
                Process process = pb.start();
                // 获取脚本输出
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line;
                while ((line = reader.readLine()) != null) {
                    // 检查是否包含URL
                    if (line.contains("url:")) {
                        // 提取并打印URL内容
                        outputUrl = line.substring(line.indexOf("url:") + 4).trim();
                        System.out.println("Extracted URL: " + outputUrl);
                        // 你可以在这里对URL进行进一步处理，比如发送HTTP请求等
                    } else {
                        // 打印普通输出
                        System.out.println(line);
                    }
                }
                // 等待脚本执行完成
                int exitCode = process.waitFor();
                System.out.println("Exited with code: " + exitCode);

            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
        }

        }
        else {
            return ResultUtils.error(-1, "请求失败");
        }

        if(outputUrl == null){
            return ResultUtils.error(-1, "请求失败");
        }
        return ResultUtils.success(outputUrl);
    }

    public JsonResult createMaterial(CreateConceptMaterialDTO createConceptMaterialDTO, MultipartFile imgFile, String userId) {
        try{
            // 定义允许的图片类型
//            List<String> allowedContentTypes = Arrays.asList(
//                    MediaType.IMAGE_JPEG_VALUE,  // "image/jpeg"
//                    MediaType.IMAGE_PNG_VALUE,   // "image/png"
//                    MediaType.IMAGE_GIF_VALUE    // "image/gif"
//            );
//
//            //判断文件类型
//            if (!allowedContentTypes.contains(imgFile.getContentType())) {
//                return ResultUtils.error(-1,"文件类型不允许");
//            }

            ConceptMaterial conceptMaterial =new ConceptMaterial();
            BeanUtils.copyProperties(createConceptMaterialDTO, conceptMaterial);

            //图像
            if (imgFile.isEmpty()) {
                conceptMaterial.setMaterialWebAddress("");
            }else {
                File folder = new File(conceptMaterialUploadDir);
                if (!folder.isDirectory()) {
                    folder.mkdirs();
                }
                //将文件保存到指定位置
                String materialFileName = imgFile.getOriginalFilename(); //eg: XXX.js
                String materialFileMainName= FileNameUtil.mainName(materialFileName); // XXX
                String materialFileExtName = FileNameUtil.extName(materialFileName); //js
                String materialFileNewName= IdUtil.objectId()+"."+materialFileExtName;
                File saveImgFile = new File(folder, materialFileNewName);//eg: E:\\TEMP\\1231231.js
                imgFile.transferTo(saveImgFile);
                conceptMaterial.setMaterialStoreName(materialFileNewName);
                conceptMaterial.setMaterialWebAddress("/store/conceptMaterialFile/"+materialFileNewName);
                conceptMaterial.setMaterialRelativePath("/conceptMaterialFile/"+materialFileNewName);
            }
            UserEntity user = userDao.findByUserId(userId);
            conceptMaterial.setCreatorId(user.getUserId());
            conceptMaterial.setCreatorName(user.getName());
            conceptMaterial.setCreatorEmail(user.getEmail());
            conceptMaterialDao.save(conceptMaterial);

            return ResultUtils.success("创建模型条目成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"创建模型条目失败！");
        }
    }

    public JsonResult searchMaterialList(ConceptMaterialPageDTO conceptMaterialFindDTO) {
        try{
            Pageable pageable = commonService.getConceptMaterialPageable(conceptMaterialFindDTO);
            String type = conceptMaterialFindDTO.getCurQueryField();
            Page<ConceptMaterial> re;
            if(type.equals("name")){
                re = conceptMaterialDao.findAllByNameLikeIgnoreCase(conceptMaterialFindDTO.getSearchText(),pageable);
            }else {
                re = conceptMaterialDao.findAllByDescriptionLikeIgnoreCase(conceptMaterialFindDTO.getSearchText(),pageable);
            }
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败！");
        }
    }

    public JsonResult getMaterialById(String materialId) {
        try{
            Optional<ConceptMaterial> conceptMaterialDB = conceptMaterialDao.findById(materialId);
            if(!conceptMaterialDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            ConceptMaterial conceptMaterial = conceptMaterialDB.get();
            return ResultUtils.success(conceptMaterial);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目信息获取失败！");
        }
    }

    public JsonResult deleteMaterial(String materialId) {
        try {
            ConceptMaterial conceptMaterialDB = conceptMaterialDao.findById(materialId).get();

            String filePath = conceptMaterialUploadDir + "/" + conceptMaterialDB.getMaterialStoreName();
            FileUtil.del(filePath);

            conceptMaterialDao.deleteById(materialId);
            return ResultUtils.success("删除资源数据成功！");
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1, "删除资源数据失败！");
        }
    }

}